package com.mzj.saas.mservice.records.service;

import com.alibaba.fastjson.JSON;
import com.mzj.saas.commons.*;
import com.mzj.saas.commons.enums.*;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.config.oss.OssConfig;
import com.mzj.saas.mservice.application.entity.HousePutRecordsSet;
import com.mzj.saas.mservice.application.repository.HousePutRecordsSetRepository;
import com.mzj.saas.mservice.area.entity.Area;
import com.mzj.saas.mservice.area.repository.AreaRepository;
import com.mzj.saas.mservice.area.service.AreaService;
import com.mzj.saas.mservice.backlog.entity.BacklogItem;
import com.mzj.saas.mservice.backlog.entity.BacklogItemApprove;
import com.mzj.saas.mservice.backlog.entity.BacklogItemRecord;
import com.mzj.saas.mservice.backlog.entity.BacklogItemRecordSubmit;
import com.mzj.saas.mservice.backlog.repository.BacklogItemApproveRepository;
import com.mzj.saas.mservice.backlog.repository.BacklogItemRecordRepository;
import com.mzj.saas.mservice.backlog.repository.BacklogItemRecordSubmitRepository;
import com.mzj.saas.mservice.backlog.repository.BacklogItemRepository;
import com.mzj.saas.mservice.contract.entity.Contract;
import com.mzj.saas.mservice.contract.repository.ContractRepository;
import com.mzj.saas.mservice.eligible.entity.*;
import com.mzj.saas.mservice.eligible.repository.*;
import com.mzj.saas.mservice.eligible.service.EligibleService;
import com.mzj.saas.mservice.house.entity.Cohabit;
import com.mzj.saas.mservice.house.entity.CohabitOld;
import com.mzj.saas.mservice.house.entity.House;
import com.mzj.saas.mservice.house.entity.HouseMatchUser;
import com.mzj.saas.mservice.house.repository.CohabitOldRepository;
import com.mzj.saas.mservice.house.repository.CohabitRepository;
import com.mzj.saas.mservice.house.repository.HouseMatchUserRepository;
import com.mzj.saas.mservice.house.repository.HouseRepository;
import com.mzj.saas.mservice.lock.Repository.SmartLockAuthRepository;
import com.mzj.saas.mservice.lock.Repository.SmartLockRepository;
import com.mzj.saas.mservice.lock.entity.SmartLock;
import com.mzj.saas.mservice.lock.entity.SmartLockAuth;
import com.mzj.saas.mservice.oss.service.OSSService;
import com.mzj.saas.mservice.records.entity.HousePutLiability;
import com.mzj.saas.mservice.records.entity.HousePutRecords;
import com.mzj.saas.mservice.records.repository.HousePutLiabilityRepository;
import com.mzj.saas.mservice.records.repository.HousePutRecordsRepository;
import com.mzj.saas.mservice.records.vo.*;
import com.mzj.saas.mservice.sys.entity.AppUser;
import com.mzj.saas.mservice.sys.repository.AppUserRepository;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class RecordsService {
    private static final Logger log = LoggerFactory.getLogger(RecordsService.class);

    private static final String RECORDS_COUNT = "SELECT COUNT(1) ";
    private static final String RECORDS_COLUM = "SELECT h.id AS houseId,h.org_id AS orgId,h.province_id AS provinceId,h.city_id AS cityId,\n" +
            "h.district_id AS districtId,h.street_id AS streetId,h.community_id AS communityId,\n" +
            "u.match_user_id AS matchUserId,u.apply_id AS applyId,r.`id` AS recordsId,r.`submit_time` AS submitTime,\n" +
            "r.`status`,r.`confirm_time` AS confirmTime,r.signature_file as signatureFile,r.type,h.record_change_status as recordChangeStatus";
    private static final String RECORDS_FROM_MONITOR = " FROM (SELECT * FROM saas_house h WHERE h.payment_status = 1) h \n" +
            "LEFT JOIN (SELECT * FROM saas_house_match_user WHERE STATUS = 1) u ON h.id = u.`house_id`\n" +
            "left join saas_house_put_records r on h.id = r.`house_id`";
    private static final String RECORDS_FROM_MONITOR_MORE = " FROM (SELECT * FROM saas_house_match_user WHERE STATUS = 1) u "
            + "LEFT JOIN (SELECT * FROM saas_house h WHERE h.payment_status = 1) h ON h.id = u.`house_id` "
            + "LEFT JOIN saas_house_put_records r ON u.match_user_id = r.`match_user_id`";

    private static final String RECORDS_ORDER = " ORDER BY h.create_time DESC";
    private static final String LIABILITY_ORDER = " ORDER BY l.create_time DESC";
    private static final String SQL_PAGE = " LIMIT ? OFFSET ?";

    @Autowired
    private RedisService redisService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private OSSService ossService;
    @Autowired
    private OssConfig ossConfig;
    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redisTemplate;
    @Autowired
    private HousePutRecordsRepository housePutRecordsRepository;
    @Autowired
    private HousePutLiabilityRepository housePutLiabilityRepository;
    @Autowired
    private HouseRepository houseRepository;
    @Autowired
    private HousePutRecordsSetRepository housePutRecordsSetRepository;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private BacklogItemRepository backlogItemRepository;
    @Autowired
    private BacklogItemRecordRepository backlogItemRecordRepository;
    @Autowired
    private AreaRepository areaRepository;
    @Autowired
    private CohabitRepository cohabitRepository;
    @Autowired
    private ApplyAuditRepository applyAuditRepository;
    @Autowired
    private BacklogItemApproveRepository backlogItemApproveRepository;
    @Autowired
    private EligibleRepository eligibleRepository;
    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private AreaService areaService;
    @Autowired
    private HouseCohabitMaterialRepository houseCohabitMaterialRepository;
    @Autowired
    private EligibleService eligibleService;
    @Autowired
    private HouseApplyFlowRepository houseApplyFlowRepository;
    @Autowired
    private HouseMatchUserRepository houseMatchUserRepository;
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;
    @Autowired
    private SmartLockRepository smartLockRepository;
    @Autowired
    private SmartLockAuthRepository smartLockAuthRepository;
    @Autowired
    private EligibleOldRepository eligibleOldRepository;
    @Autowired
    private HouseApplyMaterialRepository houseApplyMaterialRepository;
    @Autowired
    private HouseApplyMaterialOldRepository houseApplyMaterialOldRepository;
    @Autowired
    private CohabitOldRepository cohabitOldRepository;
    @Autowired
    private HouseCohabitMaterialOldRepository houseCohabitMaterialOldRepository;
    @Autowired
    private HouseApplyFlowOldRepository houseApplyFlowOldRepository;
    @Autowired
    private ApplyAuditOldRepository applyAuditOldRepository;
    @Autowired
    private BacklogItemRecordSubmitRepository backlogItemRecordSubmitRepository;

    /**
     * 信息备案列表,实现了信息备案列表的查询
     *
     * @param accessToken 权限鉴定
     * @param status      状态，0：待确认，1：已确认
     * @param pageNumber  当前页
     * @param pageSize    页数
     * @return
     */
    public ResultBean<ApiData<RecordsListVO>> recordsList(String accessToken, Integer status, Integer pageNumber, Integer pageSize) {
        //默认返回成功
        ResultBean<ApiData<RecordsListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<RecordsListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //获取企业ID
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            //判断状态是否为空
            if (status == null) {
                return ResultBean.failedResultWithMsg("状态id为空");
            }

            /*
            1、承租人：查询自己申请的公租房备案信息。
            2、产权单位：查询绑定了该产权单位的公租房备案信息列表。
            3、确认人：查询确认人设置表区域所有公租房的信息备案列表。
             */
            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where h.id is not null");
            where.append(" and (u.match_user_id = ? or h.org_id = ? or h.province_id = ? or h.city_id = ? " +
                    "or h.district_id = ? or h.street_id = ? or h.community_id = ?)");
            //根据用户ID获取公租房配租成功记录表
            List<HouseMatchUser> matchUserList = houseMatchUserRepository.findByMatchUserIdAndStatus(userId, 1);

            Integer isOrg = 0;//产权单位标识：0否，1是
            DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
            if (hierarchy != null) {
                List<DepartmentEnterpriseTagRef> refs = departmentEnterpriseTagRefRepository.findByDepRefId(hierarchy.getId());
                if (!refs.isEmpty()) {
                    List<Long> enterpriseTagIds = refs.stream().map(DepartmentEnterpriseTagRef::getTagId).distinct().collect(Collectors.toList());
                    if (enterpriseTagIds.contains(2L)) {
                        isOrg = 1;
                    }
                }
            }

            Long areaId = null;
            //根据区域社区id获取公租房信息备案确定人设置表
            HousePutRecordsSet recordsSet = housePutRecordsSetRepository.findByConfirmorIdAndStatus(userId, 1);
            if (recordsSet != null) {
                areaId = recordsSet.getAreaId();
            }

            if (matchUserList.isEmpty()) {
                //不是承租人、不是产权单位、是确认人，不查未提交数据
                if (isOrg == 0 && recordsSet != null) {
                    where.append(" and r.id is not null");
                }
            } else {
                //是承租人、已提交备案、不是产权单位、是确认人，不查未提交数据
                HouseMatchUser houseMatchUser = matchUserList.get(0);
                HousePutRecords housePutRecords = housePutRecordsRepository.findByMatchUserId(houseMatchUser.getMatchUserId());
                if (housePutRecords != null && isOrg == 0 && recordsSet != null) {
                    where.append(" and r.id is not null");
                }
            }

            args.add(userId);
            args.add(enterpriseId);
            args.add(areaId);
            args.add(areaId);
            args.add(areaId);
            args.add(areaId);
            args.add(areaId);

            if (status == 0) {//待确认
                where.append(" and (r.`status` = ? or r.id is null)");
                args.add(status);
            } else if (status == 1) {//已确认
                where.append(" and r.`status` = ?");
                args.add(status);
            }

            //总数
            Long total = jdbcTemplate.queryForObject(RECORDS_COUNT + RECORDS_FROM_MONITOR_MORE + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }
            //设置当前页
            args.add(pageSize);
            //设置页数
            args.add(pageNumber * pageSize);
            List<RecordsListVO> recordsList = jdbcTemplate.query(RECORDS_COLUM + RECORDS_FROM_MONITOR_MORE + where + RECORDS_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(RecordsListVO.class), args.toArray());

            for (RecordsListVO vo : recordsList) {
                vo.setSubmitTime(vo.getSubmitTime() == null ? "" : DateUtils.format(vo.getSubmitTime(), DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
                vo.setConfirmTime(vo.getConfirmTime() == null ? "" : DateUtils.format(vo.getConfirmTime(), DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
            }

            // 查询承租人名称
            List<String> ids = recordsList.stream().filter(vo -> vo.getMatchUserId() != null).map(RecordsListVO::getMatchUserId).distinct().collect(Collectors.toList());
            if (!ids.isEmpty()) {
                List<AppUser> appUsers = appUserRepository.findByIdOrEnterpriseIn(ids, ids);
                for (AppUser appUser : appUsers) {
                    for (RecordsListVO vo : recordsList) {
                        if (vo.getMatchUserId() != null) {
                            if (vo.getMatchUserId().equals(appUser.getId()) || vo.getMatchUserId().equals(appUser.getEnterpriseUserId())) {
                                vo.setMatchUserName(appUser.getName());
                            }
                        }
                    }
                }
            }

            //承租人、确认人标识
            for (RecordsListVO vo : recordsList) {
                if (userId.equals(vo.getMatchUserId() == null ? "" : vo.getMatchUserId())) {
                    vo.setMatchUserFlag(1);
                } else {
                    vo.setMatchUserFlag(0);
                }

                if (areaId != null && (vo.getProvinceId() == areaId.longValue() || vo.getCityId() == areaId.longValue()
                        || vo.getDistrictId() == areaId.longValue() || vo.getStreetId() == areaId.longValue()
                        || vo.getCommunityId() == areaId.longValue())) {
                    vo.setConfirmFlag(1);
                } else {
                    vo.setConfirmFlag(0);
                }
            }

            apiData.setData(recordsList);
            apiData.setTotal(total);
            resultBean.setResultData(apiData);
        } catch (Exception e) {
            log.error("RecordsService recordsList Exception = {}" + e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        resultBean.setResultData(apiData);
        return resultBean;
    }

    public ResultBean<Map<String, Object>> liabilityContent(Long communityId) {
        try {
            if (communityId == null) {
                return ResultBean.failedResultOfParamWithMsg("社区id为空");
            }

            HousePutLiability housePutLiability = housePutLiabilityRepository.findByCommunityIdAndEnableStatusAndStatus(communityId, 1, 1);
            if (housePutLiability == null) {
                return ResultBean.successfulResult(null);
            }
            String liabilityNumber = housePutLiability.getLiabilityNumber();
            String content = housePutLiability.getContent();

            Map<String, Object> map = new HashMap<>();
            map.put("liabilityNumber", liabilityNumber);
            map.put("content", content);

            return ResultBean.successfulResult(map);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 上传签字图片，实现签字图片的上传
     *
     * @param houseId 公租房id
     * @param file 签字图片
     * @return
     */
    public ResultBean<Object> uploadSign(String houseId, MultipartFile file) {
        try {
            //判断公租房ID是否为空
            if (StringUtils.isBlank(houseId)) {
                return ResultBean.failedResultOfParamWithMsg("公租房id为空");
            }
            //判断文件是否为空
            if (file == null) {
                return ResultBean.failedResultOfParamWithMsg("上传文件为空");
            }
            //如果有缓存，先删除上传文件
            Object object = redisTemplate.opsForValue().get("records:fileKey:" + houseId);
            if (object != null) {
                String fileKey = object.toString();
                ossService.deleteObject(ossConfig.getOssBucketName(), fileKey);
            }
            //上传成功后，重新设置缓存
            ResultBean<Object> objectResultBean = ossService.putFile(ossConfig.getOssBucketName(), file, OSSUploadFileTypeEnum.SIGN.toString());
            String fileKey = objectResultBean.getResultData().toString();
            redisTemplate.opsForValue().set("records:fileKey:" + houseId, fileKey, 5, TimeUnit.MINUTES);
            String url = ossService.getOssFilePath(fileKey);
            //给前端返回签字图片地址
            return ResultBean.successfulResult(url);
        } catch (Exception e) {
            //记录错误日志
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 提交信息备案
     *
     * @param accessToken 权限鉴定
     * @param liabilityNumber 责任书序号
     * @param houseId 公租房id
     * @param matchUserId 承租人id
     * @param applyId 申请id
     * @param signatureFile 签字文件url
     * @return
     */
    public ResultBean<Object> submitRecords(String accessToken, String liabilityNumber, String houseId, String matchUserId,
                                            Long applyId, String signatureFile, Long orgId) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //获取企业ID
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            //判断公租房ID是否为空
            if (StringUtils.isBlank(houseId)) {
                return ResultBean.failedResultOfParamWithMsg("公租房id为空");
            }
            //判断承租人ID是否为空
            if (StringUtils.isBlank(matchUserId)) {
                return ResultBean.failedResultOfParamWithMsg("承租人id为空");
            }
            //判断申请ID是否为空
            if (applyId == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }
            //判断文件路基是否为空
            if (StringUtils.isBlank(signatureFile)) {
                return ResultBean.failedResultOfParamWithMsg("签字文件路径为空");
            }
            //判断产权单位是否为空
            if (orgId == null) {
                return ResultBean.failedResultOfParamWithMsg("产权单位id为空");
            }
            //根据承租人ID获取用户信息
            AppUser user = appUserRepository.findByIdOrEnterpriseUserId(matchUserId, matchUserId);
            if (user == null) {
                return ResultBean.failedResultWithMsg("承租人数据不存在");
            }
            //根据公租房ID获取公租房信息
            Optional<House> houseOptional = houseRepository.findById(houseId);
            if (!houseOptional.isPresent()) {
                return ResultBean.failedResultWithMsg("公租房不存在");
            }
            House house = houseOptional.get();

            Date date = new Date();
            //根据公租房ID、承租人id、申请id获取信息备案记录表
            List<HousePutRecords> recordsList = housePutRecordsRepository.findByHouseIdAndMatchUserIdAndApplyId(houseId, matchUserId, applyId);
            if (!recordsList.isEmpty()) {
                return ResultBean.failedResultWithMsg("已存在备案信息，不可重复提交");
            }
            HousePutRecords records = new HousePutRecords();
            if (!StringUtils.isBlank(liabilityNumber)) {
                records.setLiabilityNumber(liabilityNumber);
            }
            //设置信息备案记录表
            records.setType(1);//1公租房资格申请
            records.setHouseId(houseId);
            records.setMatchUserId(matchUserId);
            records.setApplyId(applyId);
            records.setStatus(0);//待确认
            records.setSignatureFile(signatureFile);
            records.setSubmitTime(date);
            HousePutRecords recordsSave = housePutRecordsRepository.save(records);

            //修改合同状态已备案履约中
            Contract contract = contractRepository.findByHouseIdAndMatchUserId(houseId, matchUserId);
            if (contract == null) {
                log.info("RecordsService submitRecords ----> 合同不存在 ,houseId = {} , matchUserId = {}", houseId, matchUserId);
                return ResultBean.failedResultWithMsg("合同不存在");
            }
            contract.setStatus(ContractStatusEnum.WAITING_PERFORMANCE.getValue());
            contractRepository.save(contract);

            //更新备案待提交待办事项
            BacklogItemRecordSubmit recordSubmit = backlogItemRecordSubmitRepository.findByMatchUserId(matchUserId);
            if (recordSubmit != null) {
                Optional<BacklogItem> itemOptional = backlogItemRepository.findById(recordSubmit.getBacklogItemId());
                if (itemOptional.isPresent()) {
                    BacklogItem item = itemOptional.get();
                    item.setBusinessStatus("已提交");
                    item.setHandleStatus(1);
                    item.setHandlerTime(date);
                    backlogItemRepository.save(item);
                }
            }

            //生成备案待确认待办事项
            BacklogItem backlogItem = new BacklogItem();
            backlogItem.setHouseId(houseId);
            if (enterpriseId != null) {
                backlogItem.setUserOrgId(enterpriseId);
            }
            backlogItem.setType(BacklogItemTypeEnum.RECORD.getValue());
            backlogItem.setTitle(user.getName() + "提交的信息备案待确认");
            backlogItem.setBusinessStatus("待确认");
            backlogItem.setHandleStatus(0);//0未读/未处理
            backlogItem.setOperatorId(userId);
            backlogItem.setMatchUserId(matchUserId);
            backlogItem.setPhone(user.getPhone());
            backlogItem.setCreateTime(date);
            backlogItem.setCommunityId(house.getCommunityId());
            BacklogItem save = backlogItemRepository.save(backlogItem);

            BacklogItemRecord backlogItemRecord = new BacklogItemRecord();
            backlogItemRecord.setBacklogItemId(save.getId());
            backlogItemRecord.setRecordsId(recordsSave.getId());
            backlogItemRecord.setMatchUserId(matchUserId);
            backlogItemRecordRepository.save(backlogItemRecord);
            //返回成功标识给前端页面
            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 确认信息备案
     *
     * @param accessToken 权限鉴定
     * @param recordsId 信息备案id
     * @return
     */
    public ResultBean<Object> confirmRecords(String accessToken, Long recordsId) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //判断信息备案ID是否为空
            if (recordsId == null) {
                return ResultBean.failedResultOfParamWithMsg("信息备案id为空");
            }
            //根据信息备案ID查询信息备案记录表
            Optional<HousePutRecords> optional = housePutRecordsRepository.findById(recordsId);
            if (!optional.isPresent()) {
                return ResultBean.failedResultWithMsg("信息备案记录为空");
            }
            //获取信息备案数据
            HousePutRecords records = optional.get();
            if (records.getStatus() == 1) {
                return ResultBean.failedResultWithMsg("信息备案已确认，不可重复确认");
            }
            //通过公租房ID获取公租房信息
            Optional<House> houseOptional = houseRepository.findById(records.getHouseId());
            if (!houseOptional.isPresent()) {
                return ResultBean.failedResultWithMsg("公租房不存在");
            }
            House house = houseOptional.get();
            //设置存储信息备案数据
            Date date = new Date();
            records.setStatus(1);//已确认
            records.setConfirmorId(userId);
            records.setConfirmTime(new Date());
            housePutRecordsRepository.save(records);
            //修改公租房备案状态
            house.setRecordStatus(1);//已备案
            houseRepository.save(house);

            //更新备案待确认待办事项
            BacklogItemRecord backlogItemRecord = backlogItemRecordRepository.findByRecordsId(recordsId);
            if (backlogItemRecord != null) {
                Optional<BacklogItem> itemOpt = backlogItemRepository.findById(backlogItemRecord.getBacklogItemId());
                if (itemOpt.isPresent()) {
                    BacklogItem backlogItem = itemOpt.get();
                    backlogItem.setBusinessStatus("已确认");
                    backlogItem.setHandleStatus(1);
                    backlogItem.setHandlerTime(new Date());
                    backlogItemRepository.save(backlogItem);
                }
            }

            //如果房屋已安装智能锁，同步用户数据
            List<SmartLock> lockList = smartLockRepository.findByHouseId(house.getId());
            if (!lockList.isEmpty()) {
                SmartLock smartLock = lockList.get(0);

                List<HouseMatchUser> houseMatchUser = houseMatchUserRepository.findHouseIdAndStatus(house.getId(), 1);
                if (houseMatchUser.isEmpty()) {
                    log.info("RecordsService confirmRecords 配租记录不存在, houseId={}", house.getId());
                    return ResultBean.failedResultWithMsg("配租记录不存在");
                }

                HouseMatchUser matchUser = houseMatchUser.get(0);
                //生成承租人授权明细
                SmartLockAuth matchAuth = new SmartLockAuth();
                //设置保存公租房配租成功记录表
                matchAuth.setLockId(smartLock.getId());
                matchAuth.setHouseId(house.getId());
                matchAuth.setBindType(0);//单位
                matchAuth.setMatchUserId(matchUser.getMatchUserId());
                matchAuth.setAuthorUserId(matchUser.getMatchUserId());
                AppUser user = appUserRepository.findByIdOrEnterpriseUserId(matchUser.getMatchUserId(), matchUser.getMatchUserId());
                if (user == null) {
                    return ResultBean.failedResultWithMsg("承租人不存在");
                }
                //设置保存公租房配租成功记录表
                matchAuth.setUserName(user.getName());
                matchAuth.setMobile(user.getPhone());
                matchAuth.setRelationTag(1);//户主
                matchAuth.setPwdStatus(0);
                matchAuth.setFingerprintStatus(0);
                matchAuth.setCardStatus(0);
                matchAuth.setCpuStatus(0);
                matchAuth.setBleStatus(0);
                matchAuth.setCreateTime(date);
                matchAuth.setUserType(1);
                smartLockAuthRepository.save(matchAuth);

                //更新智能锁承租人信息
                smartLock.setMatchUserId(matchUser.getMatchUserId());
                smartLock.setMatchUserName(user.getName());
                smartLockRepository.save(smartLock);

                //生成同住人授权明细
                Long applyId = matchUser.getApplyId();
                List<Cohabit> cohabits = cohabitRepository.findByApplyId(applyId);
                for (Cohabit cohabit : cohabits) {
                    //设置保存同住人信息数据
                    SmartLockAuth cohabitAuth = new SmartLockAuth();
                    cohabitAuth.setLockId(smartLock.getId());
                    cohabitAuth.setHouseId(house.getId());
                    cohabitAuth.setBindType(0);//单位
                    cohabitAuth.setMatchUserId(matchUser.getMatchUserId());
                    cohabitAuth.setAuthorUserId(cohabit.getId());
                    cohabitAuth.setUserName(cohabit.getName());
                    cohabitAuth.setMobile(cohabit.getMobile());
                    cohabitAuth.setRelationTag(cohabit.getFamilyTiesType());
                    cohabitAuth.setPwdStatus(0);
                    cohabitAuth.setFingerprintStatus(0);
                    cohabitAuth.setCardStatus(0);
                    cohabitAuth.setCpuStatus(0);
                    cohabitAuth.setBleStatus(0);
                    cohabitAuth.setCreateTime(date);
                    cohabitAuth.setUserType(2);
                    smartLockAuthRepository.save(cohabitAuth);
                }
            }
            //返回成功标识给前端页面
            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> batchConfirmRecords(String accessToken, List<Long> recordsIds) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();

            if (recordsIds == null || recordsIds.isEmpty()) {
                return ResultBean.failedResultOfParamWithMsg("信息备案id为空");
            }

            Date date = new Date();
            for (Long recordsId : recordsIds) {
                Optional<HousePutRecords> optional = housePutRecordsRepository.findById(recordsId);
                if (!optional.isPresent()) {
                    return ResultBean.failedResultWithMsg("信息备案记录为空");
                }
                HousePutRecords records = optional.get();
                if (records.getStatus() == 1) {
                    return ResultBean.failedResultWithMsg("信息备案已确认，不可重复确认");
                }

                Optional<House> houseOptional = houseRepository.findById(records.getHouseId());
                if (!houseOptional.isPresent()) {
                    return ResultBean.failedResultWithMsg("公租房不存在");
                }
                House house = houseOptional.get();

                records.setStatus(1);//已确认
                records.setConfirmorId(userId);
                records.setConfirmTime(date);
                housePutRecordsRepository.save(records);
                //修改公租房备案状态
                house.setRecordStatus(1);//已备案
                houseRepository.save(house);

                //更新待办事项
                BacklogItemRecord backlogItemRecord = backlogItemRecordRepository.findByRecordsId(recordsId);
                if (backlogItemRecord != null) {
                    Optional<BacklogItem> itemOpt = backlogItemRepository.findById(backlogItemRecord.getBacklogItemId());
                    if (itemOpt.isPresent()) {
                        BacklogItem backlogItem = itemOpt.get();
                        backlogItem.setBusinessStatus("已确认");
                        backlogItem.setHandleStatus(1);
                        backlogItem.setHandlerTime(date);
                        backlogItemRepository.save(backlogItem);
                    }
                }

                //如果房屋已安装智能锁，同步用户数据
                List<SmartLock> lockList = smartLockRepository.findByHouseId(house.getId());
                if (!lockList.isEmpty()) {
                    SmartLock smartLock = lockList.get(0);

                    List<HouseMatchUser> houseMatchUser = houseMatchUserRepository.findHouseIdAndStatus(house.getId(), 1);
                    if (houseMatchUser.isEmpty()) {
                        log.info("RecordsService confirmRecords 配租记录不存在,houseId={}", house.getId());
                        return ResultBean.failedResultWithMsg("配租记录不存在");
                    }

                    HouseMatchUser matchUser = houseMatchUser.get(0);
                    //生成承租人授权明细
                    SmartLockAuth matchAuth = new SmartLockAuth();
                    matchAuth.setLockId(smartLock.getId());
                    matchAuth.setHouseId(house.getId());
                    matchAuth.setBindType(0);//单位
                    matchAuth.setMatchUserId(matchUser.getMatchUserId());
                    matchAuth.setAuthorUserId(matchUser.getMatchUserId());
                    AppUser user = appUserRepository.findByIdOrEnterpriseUserId(matchUser.getMatchUserId(), matchUser.getMatchUserId());
                    if (user == null) {
                        return ResultBean.failedResultWithMsg("承租人不存在");
                    }
                    matchAuth.setUserName(user.getName());
                    matchAuth.setMobile(user.getPhone());
                    matchAuth.setRelationTag(1);//户主
                    matchAuth.setPwdStatus(0);
                    matchAuth.setFingerprintStatus(0);
                    matchAuth.setCardStatus(0);
                    matchAuth.setCpuStatus(0);
                    matchAuth.setBleStatus(0);
                    matchAuth.setCreateTime(date);
                    smartLockAuthRepository.save(matchAuth);

                    //更新智能锁承租人信息
                    smartLock.setMatchUserId(matchUser.getMatchUserId());
                    smartLock.setMatchUserName(user.getName());
                    smartLockRepository.save(smartLock);

                    //生成同住人授权明细
                    Long applyId = matchUser.getApplyId();
                    List<Cohabit> cohabits = cohabitRepository.findByApplyId(applyId);
                    for (Cohabit cohabit : cohabits) {
                        SmartLockAuth cohabitAuth = new SmartLockAuth();
                        cohabitAuth.setLockId(smartLock.getId());
                        cohabitAuth.setHouseId(house.getId());
                        cohabitAuth.setBindType(0);//单位
                        cohabitAuth.setMatchUserId(matchUser.getMatchUserId());
                        cohabitAuth.setAuthorUserId(cohabit.getId());
                        cohabitAuth.setUserName(cohabit.getName());
                        cohabitAuth.setMobile(cohabit.getMobile());
                        cohabitAuth.setRelationTag(cohabit.getFamilyTiesType());
                        cohabitAuth.setPwdStatus(0);
                        cohabitAuth.setFingerprintStatus(0);
                        cohabitAuth.setCardStatus(0);
                        cohabitAuth.setCpuStatus(0);
                        cohabitAuth.setBleStatus(0);
                        cohabitAuth.setCreateTime(date);
                        smartLockAuthRepository.save(cohabitAuth);
                    }
                }
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 责任书列表，实现责任书列表的展示
     *
     * @param accessToken     权限鉴定
     * @param liabilityNumber 责任书序号
     * @param name            名称
     * @param communityId     社区Id
     * @param pageNumber      当前页
     * @param pageSize        页数
     * @return
     */
    public ResultBean<ApiData<LiabilityListVO>> liabilityList(String accessToken, String liabilityNumber, String name, Long communityId,
                                                              Integer pageNumber, Integer pageSize) {
        //默认返回成功
        ResultBean<ApiData<LiabilityListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<LiabilityListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取企业ID
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            //判断是否是企业用户
            if (enterpriseId == null) {
                return ResultBean.failedResultWithMsg("非企业用户");
            }
            //根据企业ID查询出用户层级权限
            DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
            if (hierarchy == null) {
                return ResultBean.failedResultWithMsg("用户所属机构未设置层级架构");
            }
            //获取区域ID
            long areaId = hierarchy.getAreaId();
            //获取所有下级区域
            List<Long> areaIds = new ArrayList<>();
            areaIds.add(areaId);
            areaIds.addAll(areaService.allChildByArea(areaId));

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1");
            where.append(" AND l.`status` = ? and l.community_id in " + SQLUtils.foreachIn(areaIds.size()));
            args.add(1);//正常
            args.addAll(areaIds);
            //判断责任书序号是否为空
            if (StringUtils.isNotBlank(liabilityNumber)) {
                where.append(" AND l.`liability_number` LIKE ?");
                args.add("%" + liabilityNumber + "%");
            }
            //判断名称是否为空
            if (StringUtils.isNotBlank(name)) {
                where.append(" AND l.`name` LIKE ?");
                args.add("%" + name + "%");
            }
            //判断社区ID是否为空
            if (communityId != null) {
                where.append(" AND l.`community_id` = ?");
                args.add(communityId);
            }

            //总数
            Long total = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM `saas_house_put_liability` l" + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }
            //设置当前页
            args.add(pageSize);
            //设置页数
            args.add(pageNumber * pageSize);
            //查询所有责任书
            List<LiabilityListVO> liabilityList = jdbcTemplate.query("SELECT * FROM `saas_house_put_liability` l" + where + LIABILITY_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(LiabilityListVO.class), args.toArray());

            for (LiabilityListVO vo : liabilityList) {
                vo.setCreateTime(DateUtils.format(vo.getCreateTime(), DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
            }

            // 查询小区名称
            List<Long> communityIds = liabilityList.stream().filter(vo -> vo.getCommunityId() != null).map(LiabilityListVO::getCommunityId).distinct().collect(Collectors.toList());
            if (!communityIds.isEmpty()) {
                Map<Long, String> map = areaRepository.findByIdIn(communityIds).stream().collect(Collectors.toMap(Area::getId, Area::getName));
                if (!map.isEmpty()) {
                    liabilityList.forEach(vo -> vo.setCommunityName(map.get(vo.getCommunityId())));
                }
            }
            //设置责任书列表数据
            apiData.setData(liabilityList);
            apiData.setTotal(total);
            resultBean.setResultData(apiData);
        } catch (Exception e) {
            //记录报错入职
            log.error("RecordsService liabilityList Exception = {}" + e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        //返回责任书列表数据
        resultBean.setResultData(apiData);
        return resultBean;
    }
    /**
     * 激活或禁用责任书
     *
     * @param accessToken 权限鉴定
     * @param liabilityNumber 责任书序号
     * @return
     */
    public ResultBean<Object> updateEnableStatus(String accessToken, String liabilityNumber) {
        try {
            //判断责任书序号是否为空
            if (StringUtils.isBlank(liabilityNumber)) {
                return ResultBean.failedResultOfParamWithMsg("责任书序号为空");
            }
            //根据责任书序号获取信息备案责任书
            HousePutLiability housePutLiability = housePutLiabilityRepository.findByLiabilityNumber(liabilityNumber);
            if (housePutLiability == null) {
                return ResultBean.failedResultWithMsg("责任书不存在");
            }
            //获取数据状态:1正常 2已删除
            Integer status = housePutLiability.getStatus();
            //判断责任书状态，并修改责任书状态
            if (status == HousePutLiabilityStatusEnum.DISABLED.getValue()) {
                housePutLiabilityRepository.updateEnableStatus(liabilityNumber, HousePutLiabilityStatusEnum.ENABLE.getValue());
            } else if (status == HousePutLiabilityStatusEnum.ENABLE.getValue()) {
                housePutLiabilityRepository.updateEnableStatus(liabilityNumber, HousePutLiabilityStatusEnum.DISABLED.getValue());
            }
            //返回成功标识给前端页面
            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 删除责任书
     *
     * @param accessToken 权限鉴定
     * @param liabilityNumber 责任书序号
     * @return
     */
    public ResultBean<Object> deleteLiability(String accessToken, String liabilityNumber) {
        try {
            //判断责任书序号是否为空
            if (StringUtils.isBlank(liabilityNumber)) {
                return ResultBean.failedResultOfParamWithMsg("责任书序号为空");
            }
            //根据责任书序号获取信息备案责任书
            HousePutLiability housePutLiability = housePutLiabilityRepository.findByLiabilityNumber(liabilityNumber);
            if (housePutLiability == null) {
                return ResultBean.failedResultWithMsg("责任书不存在");
            }
            //根据责任书序号删除责任书
            housePutLiabilityRepository.deleteById(liabilityNumber);
            //返回成功标识给前端页面
            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public void wordDownload(String accessToken) {
        try {
            // 读到流中
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("static/exceltemplates/公租房社区责任书.docx");

            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

            // 导出文件下载
            DownloadUtil downloadUtil = new DownloadUtil();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int len;
            try {
                while ((len = in.read(b)) > 0) {
                    bos.write(b, 0, len);
                }

                in.close();
            } catch (IOException e) {
                log.error("Download the document is failed,message:{}", e.getMessage());
            }

            downloadUtil.download(bos, response, "liability.docx");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }
    /**
     * 查询社区，实现社区的查询
     *
     * @param accessToken 权限鉴定
     * @return
     */
    public ResultBean<List<CommunityVO>> findCommunity(String accessToken) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取企业ID
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            //根据企业ID查询出用户层级权限
            DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
            if (hierarchy == null) {
                return ResultBean.failedResultWithMsg("用户所属机构未设置层级架构");
            }
            //获取标签ID
            Long tagId = hierarchy.getTagId();
            //获取社区ID
            Long areaId = hierarchy.getAreaId();

            //获取机构区域id下所有的社区
            List<CommunityVO> communityList = new ArrayList<>();
            if (tagId == 1L || tagId == 2L || tagId == 3L || tagId == 4L) {
                communityList = jdbcTemplate.query("SELECT id AS communityId,NAME AS communityName FROM \n" +
                                "(SELECT t1.id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild,t1.name,t1.level \n" +
                                "FROM (SELECT id,parent_id,NAME,LEVEL FROM `sys_area` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 \n" +
                                ") t3 \n" +
                                "WHERE ischild != 0 AND LEVEL = 5 ",
                        new BeanPropertyRowMapper<>(CommunityVO.class), new Object[]{areaId});
            } else {
                Optional<Area> areaOptional = areaRepository.findById(areaId);
                if (!areaOptional.isPresent()) {
                    return ResultBean.failedResultWithMsg("社区不存在");
                }
                Area area = areaOptional.get();
                CommunityVO communityVO = new CommunityVO();
                communityVO.setCommunityId(area.getId());
                communityVO.setCommunityName(area.getName());
                communityList.add(communityVO);
            }
            //返回社区数据给前端页面
            return ResultBean.successfulResult(communityList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 上传责任书模板
     *
     * @param accessToken 权限鉴定
     * @param communityId 社区id
     * @param file 文件
     * @return
     */
    public ResultBean<Object> wordImport(String accessToken, Long communityId, MultipartFile file) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //判断社区id是否存在
            if (communityId == null) {
                return ResultBean.failedResultWithMsg("社区id不存在");
            }
            //判断文件是否存在
            if (file == null) {
                return ResultBean.failedResultWithMsg("导入文件异常");
            }
            //判断文件类型是否正确
            if (!file.getOriginalFilename().contains(".docx")) {
                return ResultBean.failedResultWithMsg("导入文件类型异常，请使用下载模板");
            }
            //获取责任书
            List<HousePutLiability> liabilities = housePutLiabilityRepository.findByCommunityIdAndStatus(communityId, 1);
            if (liabilities != null && !liabilities.isEmpty()) {
                return ResultBean.failedResultWithMsg("所选社区已上传责任书");
            }

            Date date = new Date();
            String filename = file.getOriginalFilename();

            try {
            	/*StringBuffer content = new StringBuffer();
                InputStream inputStream = file.getInputStream();
                XWPFDocument xwpfDocument = new XWPFDocument(inputStream);
                List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();

                for (int i = 0; i < paragraphs.size(); i++) {
                    content.append(paragraphs.get(i).getText());
                }*/
                String html = WordToHtml.Word2007ToHtml(MultipartFileToFile.multipartFileToFile(file));

                HousePutLiability housePutLiability = new HousePutLiability();
                //责任书序号
                redisTemplate.opsForValue().increment("LIABILITY_NUMBER", 1);
                Object number = redisTemplate.opsForValue().get("LIABILITY_NUMBER");
                int len = 6 - number.toString().length();
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < len; i++) {
                    builder.append("0");
                }
                //设置保存信息备案责任书
                housePutLiability.setLiabilityNumber("ZRS" + DateUtils.format(date, DateUtils.FORMAT_8) + builder.toString() + number);
                //设置保存信息备案责任书
                housePutLiability.setContent(String.valueOf(html));
                housePutLiability.setName(filename.substring(0, filename.lastIndexOf(".")));
                housePutLiability.setCommunityId(communityId);
                housePutLiability.setCreateTime(date);
                housePutLiability.setEnableStatus(HousePutLiabilityStatusEnum.ENABLE.getValue());
                housePutLiability.setStatus(1);//正常
                housePutLiability.setOperatorId(userId);
                housePutLiabilityRepository.save(housePutLiability);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //返回成标识给前端页面
            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<String> findLiability(String accessToken, String liabilityNumber) {
        try {
            if (StringUtils.isBlank(liabilityNumber)) {
                return ResultBean.failedResultOfParamWithMsg("责任书序号为空");
            }

            HousePutLiability housePutLiability = housePutLiabilityRepository.findByLiabilityNumber(liabilityNumber);
            if (housePutLiability == null) {
                return ResultBean.failedResultWithMsg("责任书不存在");
            }

            String content = housePutLiability.getContent();

            return ResultBean.successfulResult(content);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<RecordCohabitVO> findRecordCohabit(CohabitParam vo) {
        try {
            log.info("RecordsService findRecordCohabit, vo={}", JSON.toJSONString(vo));
            Long applyId = vo.getApplyId();
            String cohabitId = vo.getCohabitId();
            List<String> delIds = vo.getDelIds();
            List<String> saveIds = vo.getSaveIds();
            Integer type = vo.getType();

            List<Object> args = new ArrayList<>();
            args.add(applyId);
            String delSql = "";
            if (delIds != null && !delIds.isEmpty()) {
                delSql = " and id not in " + SQLUtils.foreachIn(delIds.size());
                args.addAll(delIds);
            }

            String saveSql = "";
            if (saveIds != null && !saveIds.isEmpty()) {
                saveSql = " or id in " + SQLUtils.foreachIn(saveIds.size());
                args.addAll(saveIds);
            }

            List<Cohabit> cohabits = jdbcTemplate.query("SELECT * FROM saas_house_eligible_apply_cohabit WHERE apply_id = ? " + delSql + saveSql + " ORDER BY apply_time ASC",
                    new BeanPropertyRowMapper<>(Cohabit.class), args.toArray());
            if (cohabits.isEmpty()) {
                return ResultBean.successfulResult(null);
            }
            String id = null;

            if (type == 1) {//下一页
                if (StringUtils.isBlank(cohabitId)) {
                    //查第一个同住人
                    Cohabit cohabit = cohabits.get(0);
                    id = cohabit.getId();
                } else {
                    //查下一个同住人
                    for (int i = 0; i < cohabits.size(); i++) {
                        Cohabit cohabit = cohabits.get(i);
                        if (cohabit.getId().equals(cohabitId)) {
                            int index = i + 1;
                            //没有下一个同住人返回null
                            if (index >= cohabits.size()) {
                                return ResultBean.successfulResult(null);
                            }

                            Cohabit nextCohabit = cohabits.get(index);
                            id = nextCohabit.getId();
                            break;
                        }
                    }
                }
            }

            if (type == 2) {//上一页
                //查上一个同住人
                for (int i = 0; i < cohabits.size(); i++) {
                    Cohabit cohabit = cohabits.get(i);
                    if (cohabit.getId().equals(cohabitId)) {
                        int index = i - 1;
                        //没有上一个同住人返回null
                        if (index < 0) {
                            return ResultBean.successfulResult(null);
                        }

                        Cohabit nextCohabit = cohabits.get(index);
                        id = nextCohabit.getId();
                        break;
                    }
                }
            }

            RecordCohabitVO cohabit = jdbcTemplate.queryForObject("SELECT c.*,a.province_id,a.city_id,a.district_id,a.street_id,a.community_id\n" +
                            "FROM `saas_house_eligible_apply_cohabit` c left join saas_house_eligible_apply a on c.apply_id = a.id WHERE c.id = ?",
                    new BeanPropertyRowMapper<>(RecordCohabitVO.class), id);
            cohabit.setMonthIncomeAmount(cohabit.getMonthIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));

            Map<Integer, List<String>> map = new HashMap<>();
            List<HouseCohabitMaterial> materials = houseCohabitMaterialRepository.findByCohabitId(id);
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            List<String> list4 = new ArrayList<>();
            for (HouseCohabitMaterial material : materials) {
                Integer materialType = material.getMaterialType();
                if (materialType == 1) {
                    list1.add(material.getUrl());
                } else if (materialType == 2) {
                    list2.add(material.getUrl());
                } else if (materialType == 3) {
                    list3.add(material.getUrl());
                } else if (materialType == 4) {
                    list4.add(material.getUrl());
                }
            }
            map.put(1, list1);
            map.put(2, list2);
            map.put(3, list3);
            map.put(4, list4);
            cohabit.setFileKeys(map);

            // 户籍地、申请区域
            List<Long> ids = new ArrayList<>();
            ids.add(cohabit.getDomicileProvinceId());
            ids.add(cohabit.getDomicileCityId());
            ids.add(cohabit.getDomicileDistrictId());
            ids.add(cohabit.getProvinceId());
            ids.add(cohabit.getCityId());
            ids.add(cohabit.getDistrictId());
            ids.add(cohabit.getStreetId());
            ids.add(cohabit.getCommunityId());
            Map<Long, String> areaMap = areaRepository.findByIdIn(ids).stream()
                    .collect(Collectors.toMap(Area::getId, Area::getName));
            if (!areaMap.isEmpty()) {
                cohabit.setDomicileProvince(areaMap.get(cohabit.getDomicileProvinceId()));
                cohabit.setDomicileCity(areaMap.get(cohabit.getDomicileCityId()));
                cohabit.setDomicileDistrict(areaMap.get(cohabit.getDomicileDistrictId()));
                cohabit.setProvince(areaMap.get(cohabit.getProvinceId()));
                cohabit.setCity(areaMap.get(cohabit.getCityId()));
                cohabit.setDistrict(areaMap.get(cohabit.getDistrictId()));
                cohabit.setStreet(areaMap.get(cohabit.getStreetId()));
                cohabit.setCommunity(areaMap.get(cohabit.getCommunityId()));
            }

            return ResultBean.successfulResult(cohabit);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<String> saveRecordCohabit(String accessToken, RecordCohabitVO vo) {
        try {
            log.info("RecordsService saveRecordCohabit, vo={}", JSON.toJSONString(vo));
            if (vo.getApplyId() == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }
            if (StringUtils.isBlank(vo.getName()) || StringUtils.isBlank(vo.getEthnic())
                    || StringUtils.isBlank(vo.getBirthDate()) || StringUtils.isBlank(vo.getCardNumber())
                    || StringUtils.isBlank(vo.getCardAddress())) {
                return ResultBean.failedResultOfParamWithMsg("身份证信息为空");
            }
            if (vo.getDomicileProvinceId() == null || vo.getDomicileCityId() == null
                    || vo.getDomicileDistrictId() == null) {
                return ResultBean.failedResultOfParamWithMsg("户籍地为空");
            }
            if (vo.getFamilyTiesType() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭关系为空");
            }
            if (vo.getCultureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("文化程度为空");
            }
            if (vo.getMaritalStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("婚姻状况为空");
            }
            if (StringUtils.isBlank(vo.getMobile())) {
                return ResultBean.failedResultOfParamWithMsg("联系电话为空");
            }
            if (vo.getHealthType() == null) {
                return ResultBean.failedResultOfParamWithMsg("健康状况为空");
            }
            if (vo.getLaborCapacityType() == null) {
                return ResultBean.failedResultOfParamWithMsg("劳动能力为空");
            }
            if (vo.getWorkStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("就业状况为空");
            }
            if (vo.getWorkUnit() == null) {
                return ResultBean.failedResultOfParamWithMsg("工作单位为空");
            }
            if (vo.getMonthIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("月收入为空");
            }
            /*if (StringUtils.isBlank(vo.getFrontCardPic()) || StringUtils.isBlank(vo.getBackCardPic())) {
                return ResultBean.failedResultOfParamWithMsg("身份证照片为空");
            }*/

            //验证同住人是否重复添加
            if (!CollectionUtils.isEmpty(vo.getSaveIds())) {
                List<Object> args = new ArrayList<>();
                args.add(vo.getCardNumber());
                args.addAll(vo.getSaveIds());
                Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE card_number = ? AND id in " +
                        SQLUtils.foreachIn(vo.getSaveIds().size()), args.toArray(), Long.class);
                if (count3 > 0) {
                    return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                }
            }

            Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                    "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
            Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                    "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
            if (count1 + count2 > 0) {
                return ResultBean.failedResultWithMsg("同住人信息已有公租房申请记录，请核实后提交");
            }

            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Date date = new Date();

            Cohabit cohabit = new Cohabit();
            cohabit.setId(KeyWorker.nextId() + "");
            cohabit.setName(vo.getName());
            cohabit.setEthnic(vo.getEthnic());
            cohabit.setBirthDate(vo.getBirthDate());
            cohabit.setCardNumber(vo.getCardNumber());
            cohabit.setCardAddress(vo.getCardAddress());
            cohabit.setDomicileProvinceId(vo.getDomicileProvinceId());
            cohabit.setDomicileCityId(vo.getDomicileCityId());
            cohabit.setDomicileDistrictId(vo.getDomicileDistrictId());
            cohabit.setFamilyTiesType(vo.getFamilyTiesType());
            cohabit.setCultureType(vo.getCultureType());
            cohabit.setMaritalStatus(vo.getMaritalStatus());
            cohabit.setMobile(vo.getMobile());
            cohabit.setHealthType(vo.getHealthType());
            cohabit.setLaborCapacityType(vo.getLaborCapacityType());
            cohabit.setWorkStatus(vo.getWorkStatus());
            cohabit.setWorkUnit(vo.getWorkUnit());
            cohabit.setMonthIncomeAmount(ConvertUtils.yuan2fen(vo.getMonthIncomeAmount()));
            cohabit.setFrontCardPic(vo.getFrontCardPic());
            cohabit.setBackCardPic(vo.getBackCardPic());
            cohabit.setOperationId(userId);
            cohabit.setApplyTime(date);
            cohabit.setFacePic(vo.getFacePic());
            Cohabit save = cohabitRepository.save(cohabit);

            Map<Integer, List<String>> fileKeys = vo.getFileKeys();
            if (fileKeys != null) {
                for (Integer integer : fileKeys.keySet()) {
                    // 获取fileKey缓存
                    String redis = (String) redisTemplate.opsForHash().get("COHABIT:" + vo.getCardNumber(),
                            integer.toString());
                    List<String> fileKeyList = fileKeys.get(integer);
                    if (!StringUtils.isBlank(redis)) {
                        String[] split = redis.split(",");
                        List<String> redisList = new ArrayList<>(Arrays.asList(split));
                        // 取出缓存中多余的fileKey
                        List<String> differentList = eligibleService.listCompare(redisList, fileKeyList);
                        // 删除Oss中多余的文件
                        for (String str : differentList) {
                            ossService.deleteObject(ossConfig.getOssBucketName(), str);
                        }
                    }
                    // 生成上传文件记录
                    for (String str : fileKeyList) {
                        HouseCohabitMaterial material = new HouseCohabitMaterial();
                        material.setApplyId(vo.getApplyId());
                        material.setCohabitId(save.getId());
                        material.setMaterialType(integer);
                        String url = ossService.getOssFilePath(str);
                        material.setUrl(url);
                        houseCohabitMaterialRepository.save(material);
                    }
                }
                // 删除redis缓存
                redisTemplate.delete("COHABIT:" + vo.getCardNumber());
            }

            return ResultBean.successfulResult(save.getId());
        } catch (Exception e) {
            log.error("RecordsService saveRecordCohabit Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> saveRecordsChange(String accessToken, RecordsChangeVO vo) {
        try {
            log.info("RecordsService saveRecordsChange, vo={}", JSON.toJSONString(vo));
            Long applyId = vo.getApplyId();
            List<String> delIds = vo.getDelIds();
            List<String> saveIds = vo.getSaveIds();

            if (applyId == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id不存在");
            }
            Optional<Eligible> eligibleOpt = eligibleRepository.findById(applyId);
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();
            Date date = new Date();

            //备份原资格申请数据
            EligibleOld eligibleOld = new EligibleOld();
            BeanUtils.copyProperties(eligible, eligibleOld);
            eligibleOld.setId(null);
            eligibleOld.setApplyCode(KeyWorker.nextId() + "");
            EligibleOld eligibleOldSave = eligibleOldRepository.save(eligibleOld);

            HouseApplyFlowOld flowOld = new HouseApplyFlowOld();
            flowOld.setApplyCode(eligibleOldSave.getApplyCode());
            flowOld.setType(1);
            flowOld.setDataId(eligibleOldSave.getId().toString());
            houseApplyFlowOldRepository.save(flowOld);

            List<HouseApplyMaterial> materials = houseApplyMaterialRepository.findByApplyId(applyId);
            if (!materials.isEmpty()) {
                List<HouseApplyMaterialOld> materialOlds = new ArrayList<>();
                for (HouseApplyMaterial material : materials) {
                    HouseApplyMaterialOld materialOld = new HouseApplyMaterialOld();
                    materialOld.setApplyId(eligibleOldSave.getId());
                    materialOld.setMaterialType(material.getMaterialType());
                    materialOld.setUrl(material.getUrl());
                    materialOlds.add(materialOld);
                }
                houseApplyMaterialOldRepository.saveAll(materialOlds);
            }

            List<Cohabit> cohabits1 = cohabitRepository.findByApplyId(applyId);
            if (!cohabits1.isEmpty()) {
                for (Cohabit cohabit : cohabits1) {
                    CohabitOld cohabitOld = new CohabitOld();
                    BeanUtils.copyProperties(cohabit, cohabitOld);
                    cohabitOld.setId(KeyWorker.nextId() + "");
                    cohabitOld.setApplyId(eligibleOldSave.getId());
                    CohabitOld cohabitOldSave = cohabitOldRepository.save(cohabitOld);

                    List<HouseCohabitMaterial> cohabitMaterials = houseCohabitMaterialRepository.findByCohabitId(cohabit.getId());
                    if (!cohabitMaterials.isEmpty()) {
                        List<HouseCohabitMaterialOld> cohabitMaterialOlds = new ArrayList<>();
                        for (HouseCohabitMaterial cohabitMaterial : cohabitMaterials) {
                            HouseCohabitMaterialOld cohabitMaterialOld = new HouseCohabitMaterialOld();
                            cohabitMaterialOld.setApplyId(eligibleOldSave.getId());
                            cohabitMaterialOld.setCohabitId(cohabitOldSave.getId());
                            cohabitMaterialOld.setMaterialType(cohabitMaterial.getMaterialType());
                            cohabitMaterialOld.setUrl(cohabitMaterial.getUrl());
                            cohabitMaterialOlds.add(cohabitMaterialOld);
                        }
                        houseCohabitMaterialOldRepository.saveAll(cohabitMaterialOlds);
                    }

                    List<HouseApplyFlowOld> applyFlowOlds = houseApplyFlowOldRepository.findByApplyCodeOrderByIdDesc(eligibleOldSave.getApplyCode());
                    HouseApplyFlowOld lastFlow = applyFlowOlds.get(0);

                    HouseApplyFlowOld flowOld2 = new HouseApplyFlowOld();
                    flowOld2.setApplyCode(eligibleOldSave.getApplyCode());
                    flowOld2.setType(2);
                    flowOld2.setDataId(cohabitOldSave.getId());
                    flowOld2.setUpDataId(lastFlow.getDataId());
                    houseApplyFlowOldRepository.save(flowOld2);

                    lastFlow.setNextDataId(cohabitOldSave.getId());
                    houseApplyFlowOldRepository.save(lastFlow);
                }
            }

            //备份审批流程
            List<ApplyAudit> applyAudits1 = applyAuditRepository.findByApplyId(applyId);
            List<ApplyAuditOld> applyAuditOlds = new ArrayList<>();
            for (ApplyAudit applyAudit : applyAudits1) {
                ApplyAuditOld applyAuditOld = new ApplyAuditOld();
                BeanUtils.copyProperties(applyAudit, applyAuditOld);
                applyAuditOld.setApplyId(eligibleOldSave.getId());
                applyAuditOlds.add(applyAuditOld);
            }
            applyAuditOldRepository.saveAll(applyAuditOlds);

            //审批待办事项加备份申请id
            backlogItemApproveRepository.updateApplyIdOldByApplyId(applyId, eligibleOldSave.getId());

            if (delIds != null && !delIds.isEmpty()) {
                //更新申请资料填写流程
                for (String delId : delIds) {
                    HouseApplyFlow flow = houseApplyFlowRepository.findByDataId(delId);
                    String upDataId = flow.getUpDataId();
                    String nextDataId = flow.getNextDataId();

                    //更新上一流程
                    houseApplyFlowRepository.updateByDataId(upDataId, nextDataId);
                    //更新下一流程
                    if (StringUtils.isNotBlank(nextDataId)) {
                        houseApplyFlowRepository.updateNextDataIdByDataId(nextDataId, upDataId);
                    }
                    //删除流程
                    houseApplyFlowRepository.deleteByDataId(delId);
                }
                //删除同住人改成删除待执行
                cohabitRepository.updateStatusByIdIn(delIds, CohabitStatusEnum.DEL.getValue());
            }

            if (saveIds != null && !saveIds.isEmpty()) {
                //获取填写流程最后同住人
                List<Cohabit> cohabits = cohabitRepository.findByApplyIdAndStatusOrderByApplyTimeDesc(applyId, CohabitStatusEnum.NORMAL.getValue());
                HouseApplyFlow flow = null;
                String applyCode = null;
                String dataId = null;
                if (!cohabits.isEmpty()) {//有同住人
                    String cohabitId = cohabits.get(0).getId();
                    flow = houseApplyFlowRepository.findByDataId(cohabitId);
                    applyCode = flow.getApplyCode();
                    dataId = cohabitId;
                } else {//没有同住人
                    flow = houseApplyFlowRepository.findByDataId(applyId.toString());
                    applyCode = flow.getApplyCode();
                    dataId = applyId.toString();
                }

                List<Cohabit> saveCohabits = cohabitRepository.findByIdInOrderByApplyTimeAsc(saveIds);
                for (Cohabit saveCohabit : saveCohabits) {
                    String saveCohabitId = saveCohabit.getId();
                    int index = saveCohabits.indexOf(saveCohabit);
                    if (index == 0) {
                        //新增流程数据
                        HouseApplyFlow applyFlow = new HouseApplyFlow();
                        applyFlow.setApplyCode(applyCode);
                        applyFlow.setType(2);
                        applyFlow.setDataId(saveCohabitId);
                        applyFlow.setUpDataId(dataId);
                        houseApplyFlowRepository.save(applyFlow);
                        //更新上一流程
                        flow.setNextDataId(saveCohabitId);
                        houseApplyFlowRepository.save(flow);
                    } else {
                        //上一新增同住人
                        Cohabit cohabit = saveCohabits.get(--index);
                        HouseApplyFlow upFlow = houseApplyFlowRepository.findByDataId(cohabit.getId());
                        //新增流程数据
                        HouseApplyFlow applyFlow = new HouseApplyFlow();
                        applyFlow.setApplyCode(applyCode);
                        applyFlow.setType(2);
                        applyFlow.setDataId(saveCohabitId);
                        applyFlow.setUpDataId(cohabit.getId());
                        houseApplyFlowRepository.save(applyFlow);
                        //更新上一流程
                        upFlow.setNextDataId(saveCohabitId);
                        houseApplyFlowRepository.save(upFlow);
                    }
                }
                //更新申请id，改成新增待生效
                cohabitRepository.updateStatusAndApplyIdByIdIn(saveIds, CohabitStatusEnum.SAVE.getValue(), applyId);
            }

            //修改公租房备案信息变更状态为：变更中
            HousePutRecords records = housePutRecordsRepository.findByApplyId(applyId);
            String houseId = records.getHouseId();
            Optional<House> houseOpt = houseRepository.findById(houseId);
            if (!houseOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("公租房不存在");
            }
            House house = houseOpt.get();
            house.setRecordChangeStatus(RecordChangeStatusEnum.CHANGING.getValue());
            houseRepository.save(house);

            //修改资格申请状态
            eligible.setApplyStatus(EligibleApplyTypeEnum.RECORD_CHANGE.getValue());
            eligible.setApplyTime(date);
            eligibleRepository.save(eligible);

            //重置审批流程
            List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(applyId);
            if (applyAudits.isEmpty()) {
                return ResultBean.failedResultWithMsg("审批流程不存在");
            }
            for (ApplyAudit applyAudit : applyAudits) {
                if (applyAudit.getSortby() == 1) {
                    applyAudit.setAuditStatus(1);
                } else {
                    applyAudit.setAuditStatus(0);
                }
                applyAudit.setRemark(null);
                applyAudit.setAuditTime(null);
                applyAuditRepository.save(applyAudit);
            }

            //生成初审待办事项
            ApplyAudit applyAudit = applyAudits.get(0);
            String currentAuditId = applyAudit.getCurrentAuditId();
            if (StringUtils.isNotBlank(currentAuditId)) {
                BacklogItem backlogItem = new BacklogItem();
                backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                backlogItem.setTitle(eligible.getName() + "提交的公租房备案变更");
                backlogItem.setBusinessStatus("待审批");
                backlogItem.setHandleStatus(0);
                backlogItem.setOperatorId(eligible.getMatchUserId());
                backlogItem.setCreateTime(date);
                backlogItem.setApplyType(2);
                BacklogItem save = backlogItemRepository.save(backlogItem);

                BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                backlogItemApprove.setBacklogItemId(save.getId());
                backlogItemApprove.setApplyId(applyId);
                backlogItemApprove.setApplyAuditId(applyAudit.getId());
                backlogItemApprove.setUserId(currentAuditId);
                backlogItemApprove.setStatus(0);
                backlogItemApproveRepository.save(backlogItemApprove);
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("RecordsService saveRecordsChange Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}





